<?php
namespace froyo\cherry\Base;

use froyo\cherry\Exception\NotFoundException;

class BaseApp extends BaseObject{
	public $appName;
	public $namespace = 'app';
	public $compoments = [];
	public $route;
	public $modules = [];
	public $langFactory = null;
	protected $state;
	protected $params = [];
	protected static $instanc;
	public $response;
	public $logger;

	public function getResponse(){
		if(!$this->response)
		{
			$this->response = new BaseResponse();
		}
		return $this->response;
	}

	public function getLogger(){
		if(!$this->logger)
		{
			throw new \Exception("Must Set Logger", 1);
			
		}
		return $this->logger;
	}


	public function getComment($name){
		if(isset($this->compoments[$name]))
		{
			return $this->compoments[$name];
		}
		return null;
	}

	public function init_(){
		Cherry::setApp($this);
		parent::init_();
	}

	public function getParam($key,$default=''){
		
		if(isset($this->params[$key]))
		{
			return $this->params[$key];
		}
		return $default;
	}



	protected $request;

	const APP_STATE_BEFORE_REQEUST = 1;
	const APP_STATE_HANDLER_REQUEST = 2;
	const APP_STATE_SEND_RESPONSE = 3;
	const APP_STATE_END = 4;
	const EVENT_BEFORE_REQEUST = 'beforerequest';
	const EVENT_BEFOR_SEND_RESPONSE = 'beforeresponse';
	const EVENT_BEFOR_END = 'beforeend';	

	public function run(){
		$this->state = self::APP_STATE_BEFORE_REQEUST;
		$this->trigger(self::EVENT_BEFORE_REQEUST);
		$this->state = self::APP_STATE_HANDLER_REQUEST;
        $this->handleRequest($this->getRequest());

        $this->state = self::APP_STATE_SEND_RESPONSE;
        $this->trigger(self::EVENT_BEFOR_SEND_RESPONSE);
        $this->getResponse()->send();
        $this->state = self::APP_STATE_END;
        $this->trigger(self::EVENT_BEFOR_END);
	}


	protected function getRequest(){
		if(!$this->request)
		{
			$this->request = new BaseRequest();
		}
		return $this->request;
	}

	protected function handleRequest($request){
		$routes =  $this->request->resolve();
		return $this->handlerRoute($routes);
		
	}

	protected function handlerRoute($routes){
		$moduleName = $routes['module'];
		if(!isset($this->modules[ $moduleName ]))
		{
			throw new NotFoundException(Cherry::lang('{:data} Not Exists!',[':data'=>$moduleName.' Module']));
		}
		$class = $this->modules[ $moduleName ];
		// if(!class_exists($class))
		// {
		// 	throw new \Exception("module ".$moduleName." not exist", 1);
		// }
		$module = new $class();
		$data = $module->handler($this->request,$routes['controller'],$routes['action']);
		$response = $this->getResponse();
		if($data instanceof BaseResponse)
		{
			$this->response = $data;
		}
		else
		{
			$this->response->setData($data);
		}
	}

	public function getRoute(){
		if(!$this->route){
			$this->route = new BaseRoute();
		}
		return $this->route;
	}

	public function getLangFactory(){
		if(!$this->langFactory)
		{
			$this->langFactory = new LangFactory();
		}
		return $this->langFactory;
	}

}